package com.vf.cloud.rendering.api.service.impl;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.springframework.stereotype.Service;
import com.vf.cloud.rendering.api.service.IDownloadClient;
import com.vf.cloud.rendering.common.constant.Cache;
import com.vf.cloud.rendering.common.util.FileUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class DownloadClientImpl implements IDownloadClient {

	// private final static long per_page = 1024l * 1024l * 50l;
	ExecutorService pool = Executors.newFixedThreadPool(100);

	@Override
	public void download(String sceneId) {

		try {
			String scene_path = Cache.local.getProjectPath();
			String down_path = String.format("%s\\%s", scene_path, sceneId);
			File f = new File(down_path);
			if (f.exists()) {
				FileUtil.deleteDir(down_path);
			}
			f.mkdirs();
			download(sceneId, 0, down_path);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void download(String sceneId, long start, String down_path) {
		InputStream is = null;
		FileOutputStream fos = null;
		try {
			HttpClient client = HttpClients.createDefault();
			HttpGet httpGet = new HttpGet(String.format("http://%s:8880/down", Cache.dispatch.getIp()));
			httpGet.setHeader("Range", "bytes=" + start + "-");
			httpGet.addHeader("terminalId", Cache.local.getMac());
			httpGet.setHeader("sceneId", sceneId);

			HttpResponse response = client.execute(httpGet);
			if (response.getHeaders("message") != null && response.getHeaders("message").length > 0) {
				throw new Exception(URLDecoder.decode(response.getHeaders("message")[0].getValue(), "utf-8"));
			}

			String fName = URLDecoder.decode(response.getFirstHeader("fName").getValue(), "utf-8");
			File file = new File(down_path, fName);
			HttpEntity entity = response.getEntity();// 获取文件流对象
			is = entity.getContent();
			fos = new FileOutputStream(file);
			byte[] buffer = new byte[1024];// 定义缓冲区

			int readLength = 0;
			while ((readLength = is.read(buffer)) > 0) {
				byte[] bytes = new byte[readLength];
				System.arraycopy(buffer, 0, bytes, 0, readLength);
				fos.write(bytes);
			}

			is.close();
			fos.flush();
			fos.close();
			unZipFile(String.format("%s\\%s", down_path, fName), down_path, sceneId);
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			try {
				if (is != null)
					is.close();
			} catch (IOException e) {
			}
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
			}
		}
	}


	/**
	 * 解压zip文件到指定目录
	 * 
	 * @param inputFile   需要压缩的文件路径
	 * @param destDirPath 指定保存的目录路径
	 * @throws Exception
	 */
	public void unZipFile(String inputFile, String destDirPath, String sceneId) {
		File srcFile = new File(inputFile);// 获取当前压缩文件
		ZipInputStream zIn = null;
		InputStream in = null;
		try {

			log.info(inputFile);
			log.info(destDirPath);
			// 判断源文件是否存在
			if (!srcFile.exists()) {
				throw new Exception(srcFile.getPath() + "所指文件不存在");
			}
			// 开始解压

			in = new FileInputStream(srcFile);

			// 构建解压输入流
			zIn = new ZipInputStream(in);
			ZipEntry entry = null;
			File file = null;
			while ((entry = zIn.getNextEntry()) != null) {
				if (!entry.isDirectory()) {
					file = new File(destDirPath, entry.getName());
					if (!file.exists()) {
						new File(file.getParent()).mkdirs();// 创建此文件的上级目录
					}
					OutputStream out = new FileOutputStream(file);
					BufferedOutputStream bos = new BufferedOutputStream(out);
					int len = -1;
					byte[] buf = new byte[1024];
					while ((len = zIn.read(buf)) != -1) {
						bos.write(buf, 0, len);
					}
					// 关流顺序，先打开的后关闭
					bos.close();
					out.close();
				}
			}

			Decompression_Completed(sceneId, inputFile);
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			if (zIn != null) {
				try {

					System.out.println(">>>>>>>>>>>>>>>>>>>close");

					zIn.closeEntry();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + srcFile.delete());
		}
	}

	private void Decompression_Completed(String sceneId, String inputFile) {
		HttpClient client = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(String.format("http://%s:8880/down", Cache.dispatch.getIp()));
		httpGet.addHeader("terminalId", Cache.local.getMac());
		httpGet.setHeader("sceneId", sceneId);
		httpGet.setHeader("complete", "Decompression_Completed");

		try {
			client.execute(httpGet);
		} catch (ClientProtocolException e) {
		} catch (Exception e) {
			e.printStackTrace();
			log.info(e.getMessage());
		} finally {
		}
	}

}
